/***********************************************************************************
 * 文件名： rhc_config.h
 * 版本： 12
 * 说明：
 * 		RHC(Resistance heating controller 电阻加热控制器)，通过PWM控制发热电阻获得的电压值来
 *  控制发热，实现按照指定电压、功率、温度进行加热。
 *      目前只支持固定PWM占空比、平均电压。
 * 修改记录：
 * 	2021/04/21: 初版。 刘言。
 *  2021/05/07: 增加空载检测功能。刘言。
 *  2021/06/29: 增加正推ADC模式（模式1）支持。
 *  2021/07/07: 增加工作模式静态选择功能，增加 恒定PWM占空比模式 。
 *  2021/07/12: 增加模式切换功能。
 *  2021/07/14: 增加输出端口分压电阻比例设置。
 *  2021/07/15: 增加 负载已装入 事件： _RHC_USE_LOADED_EVENT 。现在可以同时发送多个事件。
 *  2022/04/13: 实现功率模式
 *  2022/06/08: 优化AD正推模式下的恒功率算法。刘言
 *  2023/09/06: 添加伪功率模式，多通道输出。黄均铭【未完成】
 *  2023/10/11: 添加电流检测IC模式
 *  2024/01/12: 添加回调函数配置。黄均铭
 ***********************************************************************************/
#ifndef _RHC_CONFIG_H_
#define _RHC_CONFIG_H_

// 仅包含需要的头文件，polsys驱动和组件接口不用再包含头文件
#include "board.h"

// ***************************** 功能开关 *************************************

// 定义表示启用模式切换功能，注释掉固定默认模式不可改变但可以节省代码量
#ifdef _APP_USE_MODE_SWITCH
#define _RHC_USE_MODE_SWITCH
#endif

#ifndef _RHC_USE_MODE_SWITCH
// 目标补偿值，SetTarget 时会加这个值。不同模式的单位分别为：mV,mW,℃
// 用于当输出不准时进行微调。
// 启用 模式切换功能 时无效
#define _RHC_TARGET_CPST (0)
#endif

#if (_APP_LOG_VALID != 0) && (defined _APP_USE_SMART_COMM) && (_APP_DCURVE_VALID != 0)
// 启用实际功率获取功能
#define _RHC_USE_ACTUAL_PARAM
#endif

// 启用回调函数配置
#define _RHC_USE_CALLBACK

// 定义表示启用电流检测IC
#ifdef _APP_USE_CURRENT
#define _RHC_USE_CURRENT
#endif

// 启动负载阻值测试功能函数
#define _RHC_USE_LOAD_RES

#ifdef _APP_USE_LOAD_CHECK
// 启用负载检测功能，注释掉关闭可以节省代码量
// 目前支持检测是否空载，检测原理【同过流检测】，当电流足够小时，输出电压接近电池电压。
#define _RHC_USE_LOAD_CHECK
#endif

#ifdef _APP_USE_NOLOAD_HINT
// 启用输出过程中空载提示功能，注释掉关闭可以节省代码量
// 目前支持检测是否空载，检测原理【同过流检测】，当电流足够小时，输出电压接近电池电压。
#define _RHC_USE_NOLOAD_HINT
#endif

// ***************************** 参数定义 *************************************

// 默认模式设置
// 0 - 恒定PWM占空比模式
// 1 - 稳住电压平均值模式
// 2 - 稳住电压有效值模式
// 3 - 稳住功率模式（供电电压≤4.08V才有效，高于4.08V将全功率输出）
// 4 - 稳住温度（温控）模式【未实现】
// 5 - 稳住电流（驱动）模式【未实现】
// 6 - 稳住浓度（烟雾）模式【未实现】
#define _RHC_MODE _APP_DEFAULT_MODE

// 支持的模式，1表示支持，0表示不支持，bit0-bit4分别表示5个模式：0:固定PWM 1.电压(平均值) 2.电压（有效值）3.功率 4:温度 5:电流 6:浓度
#define _RHC_VALID_MODE _APP_VALID_MODE

// ADC满值
#define _RHC_FULL_ADV ADC_FULL_VALUE

// 负载个数
#define _RHC_LOAD_NUM _APP_LOAD_NUM

#ifdef _RHC_USE_CURRENT
// 电流计算常数，电流检测IC输出电压乘这个常数就是电流值
#define _RHC_CURRENT_CNT (1000.0f / _APP_MUL_CURR / (_APP_DIV_RES * _APP_DIVRES_MUL))

#endif

// 功率模式控制策列：0-实时控制（阻值变化时电压跟着实时变化，波动较大，mos工作发热后温度上升，阻值变大，计算负载阻值偏小，控制电压偏小）
// 1-启动之前先获取阻值，根据这个阻值控制功率（输出中途负载阻值变化不会导致电压波动，中途不判断负载变化）
#define _RHC_POWER_TSELLE _APP_POWER_TSELLE

// 设计阻值，伪功率模式用这个阻值直接计算有效值
#define _RHC_RES_LOAD _APP_DEFAULT_RES

#if (_APP_DIV_RES == 0) || (defined _RHC_USE_CURRENT)
// 定义串接的参考电阻，一般是mos内阻(S28)，真功率模式用这个电阻计算电流，从而计算功率
#define _RHC_RES_REF  _APP_MOS_RES
#define _RHC_RES_MUL  _APP_MOSRES_MUL
#define _RHC_RES_DIFF 0
#else
// 定义串接的参考电阻，一般是mos内阻(S28)，真功率模式用这个电阻计算电流，从而计算功率
#define _RHC_RES_REF  _APP_DIV_RES
#define _RHC_RES_MUL  _APP_DIVRES_MUL
#define _RHC_RES_DIFF _APP_MOS_RES
#endif

#ifdef _RHC_USE_LOAD_CHECK
// 检测负载变化，连续多次检测到空载才调用事件通知。
#define _RHC_NO_LOAD_FILTERING_CNT 30

#endif

#ifdef _RHC_USE_NOLOAD_HINT
// 允许检测到空载的次数，连续多次检测到空载才调用事件通知。
#define _RHC_NO_LOAD_ALLOW_CNT 30

#endif

#ifdef _RHC_USE_CURRENT
// 设置过流AD值
// 当电流检测IC输出口的AD值大于以下值认为过流。
#define _RHC_OC_ADVH ((float)_RHC_FULL_ADV / ((float)_APP_SHORT_RES / 1000.0f) / _RHC_CURRENT_CNT)
#else
// 设置过流AD值
// 过流检测原理：【以电池电压为ADC参考电压】，当电流越大，输出电压将越低于电池电压。
// 当输出端口上的AD值处于以下范围认为过流。一般情况下 _RHC_OC_ADVL = 0，某些特殊硬件可能要求不为0。
#define _RHC_OC_ADVH (_APP_SHORT_VALUE + (_APP_ADC_PRECISION * _APP_SHORT_VALUE * 15)) // 范围上限

#if _APP_DIV_RES == 0
// 范围下限
#define _RHC_OC_ADVL 1
#else
// 范围下限
#define _RHC_OC_ADVL 0
#endif

#endif

#ifdef _RHC_USE_CURRENT
// 设置空载AD值，【以电池电压为ADC参考电压】，当电流检测IC输出口AD值小于等于这个值时认为空载。
#define _RHC_NO_LOAD_ADV ((float)_RHC_FULL_ADV / ((float)_APP_NO_LOAD_RES / 1000.0f) / _RHC_CURRENT_CNT)
#else
// 设置空载AD值，【以电池电压为ADC参考电压】，当输出端口AD值大于等于这个值时认为空载。
#define _RHC_NO_LOAD_ADV (_RHC_FULL_ADV * 0.99f)

#endif

// 输出端口电压分压电阻的分压比，正极电阻所占的比例
// 硬件上不建议使用分压电阻，正推模式时也不要求 OVAL 管脚电压低于ADC的VREFH。
// 无分压电阻时设置为 0
#define _RHC_OVAL_HIGH_RES 0
// 输出端口电压分压电阻的分压比，负极电阻所占的比例
// 无分压电阻时设置为 1
#define _RHC_OVAL_LOW_RES 1
// 输出端口AD通道
#define _RHC_ADCH_OVAL  ADCH_OVAL
#define _RHC_ADCH_OVAL2 ADCH_OVAL2
#define _RHC_ADCH_OVAL3 ADCH_OVAL3
#define _RHC_ADCH_OVAL4 ADCH_OVAL4

#ifdef _RHC_USE_CURRENT
// 输出端口电流AD通道
#define _RHC_ADCH_DIV ADCH_DIV
#else
// 输出端口电流AD通道
#define _RHC_ADCH_DIV ADCH_OVAL

#endif

// 电池电压AD采集模式
// 0：反推模式，使用电池电压作为AD模块正极参考电压，采集一个固定参考电压来反推电池电压
// 1: 正推模式，使用一个固定电压作为AD模块的参考电压，采集分压后的电池电压，必须设置分压比。
#define _RHC_AD_MODE 0
#if (_RHC_AD_MODE == 0)
// 内部固定参考电压值，注意不是ADC硬件的参考电压，是可被ADC采集的参考电压
// RHC要求ADC硬件正极参考电压固定为电池电压。
#define _RHC_VREF_VOLTAGE ADC_VOL_VREF
// 可校准的内部固定参考电压值
#ifdef _RHC_USE_MODE_SWITCH
#define RHC_GetVrefVoltage() _RHC_VREF_VOLTAGE
#endif

// 内部固定参考电压采集通道
#define _RHC_ADCH_VREF ADCH_VREF
#else
// ADC模块正极参考电压
#define _RHC_ADC_VREF      2000
// 电池电压分压电阻的分压比，正极电阻所占的比例
#define _RHC_VBAT_HIGH_RES 3
// 电池电压分压电阻的分压比，负极电阻所占的比例
#define _RHC_VBAT_LOW_RES  1
// 电池电压AD通道
#define _RHC_ADCH_VBAT     ADC_CH_VDD
#endif

// 定义输出通道数
#define _RHC_OUT_CHANNEL _APP_LOAD_NUM

#if _RHC_OUT_CHANNEL > 1
// 如果通道数大于1，需要确定输出模式
#define _RHC_MCH_MODE 0 // 模式0：两个通道同时输出，模式1：两个通道轮回切换输出，模式2：可配置的输出

#endif

// 使用硬件PWM
#ifdef _OUTEN_HPWM_SW

// 开启连续转换
// 1：开启，只要 _RHC_OutIsON 是真，就会不停的进行AD转换，有利于提高过流保护灵敏度
// 0：关闭，只在PWM周期开始时转换一次。
// PWM频率很低时建议开启，PWM频率4kHz以上建议关闭，具体还要依据AD转换速率来决定。
#define _RHC_KEEP_ADC 0

// 允许检测到过流的次数
// 当不为0时，连续多次检测到过流才会保护
// 需要注意，如果没有开启连续转换，多次检测到过流的时间可能较长，过长的时间会烧坏MOS。
#define _RHC_OC_ALLOW_CNT 0

// pwm最小占空比 注意：不是百分比
#define _RHC_MIN_PWM 100

#else

// 开启连续转换
// 1：开启，只要 _RHC_OutIsON 是真，就会不停的进行AD转换，有利于提高过流保护灵敏度
// 0：关闭，只在PWM周期开始时转换一次。
// PWM频率很低时建议开启，PWM频率4kHz以上建议关闭，具体还要依据AD转换速率来决定。
#define _RHC_KEEP_ADC     1

// 允许检测到过流的次数
// 当不为0时，连续多次检测到过流才会保护
// 需要注意，如果没有开启连续转换，多次检测到过流的时间可能较长，过长的时间会烧坏MOS。
#define _RHC_OC_ALLOW_CNT 1

// pwm最小占空比 注意：不是百分比
#define _RHC_MIN_PWM      20

#endif

// 输出时的电池电压下限(mV)
// 电池电压低于这个值将会停止输出并触发 RHC_EV_NO_BATTERY 事件，注意是带载时的电压。
#define _RHC_VBAT_LIMIT 2800

// ***************************** 外部API引入 *************************************

// 以下设置一些需要引用的外部函数(驱动和组件接口不用再包含头文件)

#ifdef _RHC_USE_LOAD_RES
// 负载测试前的准备
#define _RHC_BeforeLoadCheck() Polsys_DisableInt()
// 负载测试后的还原
#define _RHC_AfterLoadCheck() Polsys_EnableInt()

// 负载采集前的准备
#define _RHC_BeforeGetLoadAdv() // SUart_SendEnd()
// 负载采集后的还原
#define _RHC_AfterGetLoadAdv() // SUart_SendReady()
// 获取对应阻值
#define _RHC_GetRes(n) Dmu_Status.LoadRes[n]
// 设置对应阻值 - 引用外部全局阻值变量，减少RAM占用
#define _RHC_SetRes(n, value) Dmu_Status.LoadRes[n] = value
#endif

#ifdef _RHC_USE_LOAD_CHECK
// 获取负载状态：true有负载
#define _RHC_GetLoadStatus() Board_GetLoadStatus()
#endif

// 同步开始一次AD转换，直接返回结果值
#define _RHC_GetAdv(u8_ch) Adc_GetOnce(u8_ch)

// 异步开始一次AD转换，需要确保转换完成后 RHC_EvADCCompleted 会被调用
#define _RHC_StartADC(u8_ch) Adc_StartOnce(u8_ch, RHC_EvADCCompleted)

#if _RHC_AD_MODE == 1
// 切换ADC模块的正极参考电压为VDD，在转换OVAL通道前会被调用，也可以在这里切换通道，那么 _RHC_StartADC 定义成无视 u8_ch。
#define _RHC_SetADCVrefVDD() Adc_SetVref(ADC_VREF_VDD)
// 切换ADC模块的正极参考电压为 _RHC_ADC_VREF ，在转换电池电压通道前会被调用，也可以在这里切换通道
#define _RHC_SetADCVrefVref() Adc_SetVref(ADC_VREF_2V)
#endif

// 开启了使用硬件PWM，输出通道使用硬件pwm
#ifdef _OUTEN_HPWM_SW
// 获取此时输出（PWM电平）状态
// 如果没有合适的获取途径，可以设置成 1 ，这样只要在工作就认为PWM是高电平
// 注意：如果设置成了 1 且开启持续转换，建议 _RHC_OC_ALLOW_CNT 和 _RHC_OC_ADVL 不为 0 ，避免采集到PWM跳变沿或者无效时间段误判过流。
#define _RHC_OutIsON() 1
#else
// 获取此时输出（PWM电平）状态
// 如果没有合适的获取途径，可以设置成 1 ，这样只要在工作就认为PWM是高电平
// 注意：如果设置成了 1 且开启持续转换，建议 _RHC_OC_ALLOW_CNT 和 _RHC_OC_ADVL 不为 0 ，避免采集到PWM跳变沿或者无效时间段误判过流。
#define _RHC_OutIsON() OUTEN_IS_ON
#endif

// 使用硬件PWM
#ifdef _OUTEN_HPWM_SW
// 初始化PWM控制器
#define _RHC_InitPWM() HPwm_Init()
#if _OUTEN_HPWM_SW == 0
// 输出刹车（立即停止），停止输出时被调用。
// 停止输出后，若为正推模式，ADC参考电压不确定，可在这里切换到确定的参考电压。
#define _RHC_Brake()     \
    {                    \
        HPwm_CloseCH0(); \
        OVAL_DIGIT_MODE; \
    }

// 设置 8bit PWM值
#define _RHC_SetPWM(u8_pwm) HPwm_SetCH0(u8_pwm)

// 启动PWM输出，在 RHC_Start 时被调用
// 需要确保第1个及后续PWM周期输出开启时能触发事件 RHC_EvPWMOutON，来确保过流保护生效
#define _RHC_StartPWM()   \
    {                     \
        OVAL_ANALOG_MODE; \
        HPwm_OpenCH0();   \
    }
#else
// 输出刹车（立即停止），停止输出时被调用。
// 停止输出后，若为正推模式，ADC参考电压不确定，可在这里切换到确定的参考电压。
#define _RHC_Brake()     \
    {                    \
        HPwm_CloseCH1(); \
        OVAL_DIGIT_MODE; \
    }

// 设置 8bit PWM值
#define _RHC_SetPWM(u8_pwm) HPwm_SetCH1(u8_pwm)

// 启动PWM输出，在 RHC_Start 时被调用
// 需要确保第1个及后续PWM周期输出开启时能触发事件 RHC_EvPWMOutON，来确保过流保护生效
#define _RHC_StartPWM()   \
    {                     \
        OVAL_ANALOG_MODE; \
        HPwm_OpenCH1();   \
    }
#endif
#else
// 初始化PWM控制器
#define _RHC_InitPWM() SPwm_Init()

// 输出刹车（立即停止），停止输出时被调用。
// 停止输出后，若为正推模式，ADC参考电压不确定，可在这里切换到确定的参考电压。
#define _RHC_Brake()         \
    {                        \
        SPwm_SetValue(0, 0); \
        _SPwm_Ch0Off();      \
        OVAL_DIGIT_MODE;     \
        DIV_VDD_OFF;         \
    }

// 设置 8bit PWM值
#define _RHC_SetPWM(u8_pwm) SPwm_SetValue(0, u8_pwm)

// 启动PWM输出，在 RHC_Start 时被调用
// 需要确保第1个及后续PWM周期输出开启时能触发事件 RHC_EvPWMOutON，来确保过流保护生效
#define _RHC_StartPWM()   \
    {                     \
        DIV_VDD_ON;       \
        DIV_ANALOG_MODE;  \
        OVAL_PULL_OFF;    \
        OVAL_ANALOG_MODE; \
        SPwm_ClrCount();  \
    }
#endif

// // 获取此时输出（PWM电平）状态
// // 如果没有合适的获取途径，可以设置成 1 ，这样只要在工作就认为PWM是高电平
// // 注意：如果设置成了 1 且开启持续转换，建议 _RHC_OC_ALLOW_CNT 和 _RHC_OC_ADVL 不为 0 ，避免采集到PWM跳变沿或者无效时间段误判过流。
// #define _RHC_OutIsON()          OUTEN_IS_ON

// // 初始化PWM控制器
// #define _RHC_InitPWM()          //SPwm_Init() // 注意RGB灯同时也用了SPWM组件

// // 输出刹车（立即停止），停止输出时被调用。
// #define _RHC_Brake()            SPwm_Brake(3)

// // 设置 8bit PWM值
// #define _RHC_SetPWM(u8_pwm)     SPwm_SetValue(3,u8_pwm)

// // 启动PWM输出
// // 需要确保第1个及后续PWM周期输出开启时能触发事件 RHC_EvPWMOutON，来确保过流保护生效
// #define _RHC_StartPWM()         SPwm_ClrCount()

#endif
